use std::{fmt::Display, ops::Add};

pub fn retire_time(time: &str, tp: &str) -> String {
    let birthday = DateTime::from_str(time);
    let person = Person::from_str(tp);

    let late_retirement_mouth = person.late_retirement_mouth(birthday);
    let origin_retirement_mouth = person.origin_retirement_mouth();
    let retirement_day = birthday
        .add(late_retirement_mouth)
        .add(origin_retirement_mouth);
    let retirement_mouth = retirement_day.sub(birthday);
    if retirement_mouth % 12 == 0 {
        format!(
            "{},{},{}",
            retirement_day,
            retirement_mouth / 12,
            late_retirement_mouth
        )
    } else {
        format!(
            "{},{:.2},{}",
            retirement_day,
            retirement_mouth as f64 / 12.0,
            late_retirement_mouth
        )
    }
}

#[derive(Debug, Clone, Copy)]
pub struct DateTime {
    year: u32,
    month: u32,
}

impl DateTime {
    pub fn from_str(text: &str) -> Self {
        let mut iter = text.split("-");
        let year = iter.next().unwrap();
        let year = year.parse().unwrap();
        let month = iter.next().unwrap();
        let month = month.parse().unwrap();
        assert!(iter.next().is_none());
        Self { year, month }
    }

    pub fn sub(&self, other: Self) -> i64 {
        let mut month = (self.year as i64 - other.year as i64) * 12;
        month += self.month as i64 - other.month as i64;
        month
    }

    pub fn add(&self, month: u32) -> Self {
        let month = self.month + month - 1;
        let year = month / 12;
        Self {
            year: self.year + year,
            month: (month % 12) + 1,
        }
    }
}

impl Display for DateTime {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}-{:0>2}", self.year, self.month)
    }
}

#[derive(Debug, Clone, Copy)]
pub enum Person {
    Male,
    Female55,
    Female50,
}

impl Person {
    pub fn from_str(text: &str) -> Self {
        match text {
            "原法定退休年龄55周岁女职工" => Self::Female55,
            "原法定退休年龄50周岁女职工" => Self::Female50,
            "男职工" => Self::Male,
            _ => unreachable!(),
        }
    }

    pub fn origin_retirement_mouth(&self) -> u32 {
        match self {
            Person::Male => 60 * 12,
            Person::Female55 => 55 * 12,
            Person::Female50 => 50 * 12,
        }
    }

    pub fn late_retirement_mouth(&self, birthday: DateTime) -> u32 {
        match self {
            Person::Male => ((birthday
                .sub(DateTime {
                    year: 1965,
                    month: 1,
                })
                .add(4)
                .max(0)
                / 4) as u32)
                .min(36),
            Person::Female55 => ((birthday
                .sub(DateTime {
                    year: 1970,
                    month: 1,
                })
                .add(4)
                .max(0)
                / 4) as u32)
                .min(36),
            Person::Female50 => ((birthday
                .sub(DateTime {
                    year: 1975,
                    month: 1,
                })
                .add(2)
                .max(0)
                / 2) as u32)
                .min(60),
        }
    }
}
